<!doctype html>
<!--
To quickly iterate when developing this test, use --use-fake-ui-for-media-stream
for Chrome and set the media.navigator.permission.disabled property to true in
Firefox. You must either have a webcam/mic available on the system or use for
instance --use-fake-device-for-media-stream for Chrome.
-->

<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <title>RTCPeerConnection Connection Test</title>
</head>
<body>
  <div id="log"></div>
  <div>
    <video id="local-view" autoplay="autoplay"></video>
    <video id="remote-view" autoplay="autoplay"/>
    </video>
  </div>

  <!-- These files are in place when executing on W3C. -->
  <script src="/resources/testharness.js"></script>
  <script src="/resources/testharnessreport.js"></script>
  <script src="/common/vendor-prefix.js"
          data-prefixed-objects=
              '[{"ancestors":["navigator"], "name":"getUserMedia"},
                {"ancestors":["window"], "name":"RTCPeerConnection"},
                {"ancestors":["window"], "name":"RTCSessionDescription"},
                {"ancestors":["window"], "name":"RTCIceCandidate"}]'
          data-prefixed-prototypes=
               '[{"ancestors":["HTMLMediaElement"],"name":"srcObject"}]'>
  </script>
  <script type="text/javascript">
  var test = async_test('Can set up a basic WebRTC call.', {timeout: 5000});

  var gFirstConnection = null;
  var gSecondConnection = null;

  function getUserMediaOkCallback(localStream) {
    gFirstConnection = new RTCPeerConnection(null, null);
    gFirstConnection.onicecandidate = onIceCandidateToFirst;
    gFirstConnection.addStream(localStream);
    gFirstConnection.createOffer(onOfferCreated, failed('createOffer'));

    var videoTag = document.getElementById('local-view');
    videoTag.srcObject = localStream;
  };

  var onOfferCreated = test.step_func(function(offer) {
    gFirstConnection.setLocalDescription(offer);

    // This would normally go across the application's signaling solution.
    // In our case, the "signaling" is to call this function.
    receiveCall(offer.sdp);
  });

  function receiveCall(offerSdp) {
    gSecondConnection = new RTCPeerConnection(null, null);
    gSecondConnection.onicecandidate = onIceCandidateToSecond;
    gSecondConnection.onaddstream = onRemoteStream;

    var parsedOffer = new RTCSessionDescription({ type: 'offer',
                                                  sdp: offerSdp });
    gSecondConnection.setRemoteDescription(parsedOffer);

    gSecondConnection.createAnswer(onAnswerCreated,
                                   failed('createAnswer'));
  };

  var onAnswerCreated = test.step_func(function(answer) {
    gSecondConnection.setLocalDescription(answer);

    // Similarly, this would go over the application's signaling solution.
    handleAnswer(answer.sdp);
  });

  function handleAnswer(answerSdp) {
    var parsedAnswer = new RTCSessionDescription({ type: 'answer',
                                                   sdp: answerSdp });
    gFirstConnection.setRemoteDescription(parsedAnswer);

    // Call negotiated: done.
    test.done();
  };

  // Note: the ice candidate handlers are special. We can not wrap them in test
  // steps since that seems to cause some kind of starvation that prevents the
  // call of being set up. Unfortunately we cannot report errors in here.
  var onIceCandidateToFirst = function(event) {
    // If event.candidate is null = no more candidates.
    if (event.candidate) {
      var candidate = new RTCIceCandidate(event.candidate);
      gSecondConnection.addIceCandidate(candidate);
    }
  };

  var onIceCandidateToSecond = function(event) {
    if (event.candidate) {
      var candidate = new RTCIceCandidate(event.candidate);
      gFirstConnection.addIceCandidate(candidate);
    }
  };

  var onRemoteStream = test.step_func(function(event) {
    var videoTag = document.getElementById('remote-view');
    videoTag.srcObject = event.stream;
  });

  // Returns a suitable error callback.
  function failed(function_name) {
    return test.step_func(function() {
      assert_unreached('WebRTC called error callback for ' + function_name);
    });
  }

  // This function starts the test.
  test.step(function() {
    navigator.getUserMedia({ video: true, audio: true },
        getUserMediaOkCallback,
        failed('getUserMedia'));
  });
</script>

</body>
</html>
